home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Cream of the Crop 26
/
Cream of the Crop 26.iso
/
program
/
ddj0897.zip
/
ud897.asc
< prev
next >
Wrap
Text File
|
1997-06-20
|
4KB
|
145 lines
_Undocumented Corner_
by George Shepherd and Scot Wingo
Listing One
class ATL_NO_VTABLE CDefault :
public CComObjectRootEx<CComSingleThreadModel>,
public CComCoClass<CDefault, &CLSID_Default>,
public IDispatchImpl<IDefault, &IID_IDefault, &LIBID_ATLTESTLib>
{
public:
CDefault() {
}
DECLARE_REGISTRY_RESOURCEID(IDR_DEFAULT)
BEGIN_COM_MAP(CDefault)
COM_INTERFACE_ENTRY(IDefault)
COM_INTERFACE_ENTRY(IDispatch)
END_COM_MAP()
// IDefault
public:
};
Listing Two
template <class ThreadModel>
class CComObjectRootEx : public CComObjectRootBase
{
public:
typedef ThreadModel _ThreadModel;
typedef _ThreadModel::AutoCriticalSection _CritSec;
ULONG InternalAddRef() {
return _ThreadModel::Increment(&m_dwRef);
}
ULONG InternalRelease() {
return _ThreadModel::Decrement(&m_dwRef);
}
void Lock() {m_critsec.Lock();}
void Unlock() {m_critsec.Unlock();}
private:
_CritSec m_critsec;
};
Listing Three
class CComMultiThreadModelNoCS
{
public:
static ULONG WINAPI Increment(LPLONG p) {return InterlockedIncrement(p);}
static ULONG WINAPI Decrement(LPLONG p) {return InterlockedDecrement(p);}
typedef CComFakeCriticalSection AutoCriticalSection;
typedef CComFakeCriticalSection CriticalSection;
typedef CComMultiThreadModelNoCS ThreadModelNoCS;
};
class CComMultiThreadModel
{
public:
static ULONG WINAPI Increment(LPLONG p) {return InterlockedIncrement(p);}
static ULONG WINAPI Decrement(LPLONG p) {return InterlockedDecrement(p);}
typedef CComAutoCriticalSection AutoCriticalSection;
typedef CComCriticalSection CriticalSection;
typedef CComMultiThreadModelNoCS ThreadModelNoCS;
};
class CComSingleThreadModel
{
public:
static ULONG WINAPI Increment(LPLONG p) {return ++(*p);}
static ULONG WINAPI Decrement(LPLONG p) {return --(*p);}
typedef CComFakeCriticalSection AutoCriticalSection;
typedef CComFakeCriticalSection CriticalSection;
typedef CComSingleThreadModel ThreadModelNoCS;
};
Listing Four
Class CDefault : public IDispatch,
IDefault {
HRESULT QueryInterface(RIID riid,
void** ppv) {
if(riid == IID_IDispatch)
*ppv = (IDispatch*) this;
else if(riid == IID_IDefault)
*ppv = (IDefault*) this;
else {
*ppv = 0;
return E_NOINTERFACE;
}
((IUnknown*)(*ppv))->AddRef();
return NOERROR;
}
// AddRef, Release, and other functions
};
Listing Five
#define BEGIN_COM_MAP(x) public:
typedef x _ComMapClass;
static HRESULT WINAPI _Cache(void* pv,REFIID iid,void** ppvObject,DWORD dw){
_ComMapClass* p = (_ComMapClass*)pv;
p->Lock();
HRESULT hRes =
CComObjectRootBase::_Cache(pv, iid, ppvObject, dw);
p->Unlock();
return hRes;
}
IUnknown* GetUnknown() {
_ASSERTE(_GetEntries()[0].pFunc == _ATL_SIMPLEMAPENTRY);
return (IUnknown*)((int)this+_GetEntries()->dw);
}
HRESULT _InternalQueryInterface(REFIID iid, void** ppvObject) {
return InternalQueryInterface(this, _GetEntries(), iid, ppvObject);
}
const static _ATL_INTMAP_ENTRY* WINAPI _GetEntries() {
static const _ATL_INTMAP_ENTRY _entries[] = {
DEBUG_QI_ENTRY(x)
...
#define END_COM_MAP() {NULL, 0, 0}};\
return _entries;}
Listing Six
struct _ATL_INTMAP_ENTRY {
const IID* piid;
DWORD dw;
_ATL_CREATORARGFUNC* pFunc;
}
Listing Seven
#define offsetofclass(base,derived)((DWORD)(static_cast<base*>((derived*)8))-8)
#define COM_INTERFACE_ENTRY(x)\
{&IID_##x, \
offsetofclass(x, _ComMapClass), \
_ATL_SIMPLEMAPENTRY},
Listing Eight
const static _ATL_INTMAP_ENTRY* __stdcall _GetEntries() {
static const _ATL_INTMAP_ENTRY _entries[] = {
{&IID_IDefault,
((DWORD)(static_cast<IDefault*>((_ComMapClass*)8))-8),
((_ATL_CREATORARGFUNC*)1)},
{&IID_IDispatch,
((DWORD)(static_cast<IDispatch*>((_ComMapClass*)8))-8),
((_ATL_CREATORARGFUNC*)1)},
{0, 0, 0}
};
return _entries;
}